﻿using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.Office.Interop.Excel;

namespace BabyOffice
{
    public class ExcelFile
    {
        private const string EXCEPTION_MESSAGE_WORKBOOK_ISNULL = "未能成功初始化 Microsoft.Office.Interop.Excel.Workbook";
        private const string EXCEPTION_MESSAGE_FILE_TYPE_ERROR = "不支持的文件类型";

        Application excelApplication;
        Workbook excelWorkbook;

        public void Open(string fileFullName)
        {
            if (String.IsNullOrWhiteSpace(fileFullName))
            {
                throw new ArgumentOutOfRangeException("fileFullName");
            }

            FileInfo fileInfo = new FileInfo(fileFullName);
            if (!fileInfo.Exists)
            {
                throw new FileNotFoundException();
            }

            if (fileInfo.Extension != ".xls" && fileInfo.Extension != ".xlsx")
            {
                throw new ApplicationException(EXCEPTION_MESSAGE_FILE_TYPE_ERROR);
            }

            try
            {
                excelApplication = new Application();
                excelWorkbook = excelApplication.Workbooks.Open(fileFullName);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Close()
        {         
            try            
            {                
                if (excelWorkbook != null)
                {
                    excelWorkbook.Close(false, Type.Missing, Type.Missing);
                    excelWorkbook = null;   
                }          
            }            
            catch
            {
                excelWorkbook = null;    
            }       
   
            try    
            {        
                if (excelApplication != null)           
                {             
                    excelApplication.Quit();     
                    excelApplication = null;    
                }         
            }       
            catch 
            {              
                excelApplication = null;       
                ProcessManager.KillExcelProcess();   
            }  
        
            GC.Collect();    
            GC.WaitForPendingFinalizers(); 
            GC.Collect();        
            GC.WaitForPendingFinalizers();
        }

        public List<string> GetSheetNameList()
        {
            if (excelWorkbook == null)
            {
                throw new ApplicationException(EXCEPTION_MESSAGE_WORKBOOK_ISNULL);
            }

            List<string> sheetNameList = new List<string>();

            foreach (Worksheet workSheet in excelWorkbook.Sheets)
            {
                sheetNameList.Add(workSheet.Name);
            }                       

            return sheetNameList;
        }

        public void ConvertToPDF(string sheetName, string filePath)
        {
            if (excelWorkbook == null)
            {
                throw new ApplicationException(EXCEPTION_MESSAGE_WORKBOOK_ISNULL);
            }

            if (String.IsNullOrWhiteSpace(sheetName))
            {
                throw new ArgumentOutOfRangeException(sheetName);
            }

            if (String.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentOutOfRangeException(filePath);
            }

            try
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(filePath);
                
                if (!directoryInfo.Exists)
                {
                    directoryInfo.Create();
                }

                string fileName = directoryInfo.FullName + "\\" + sheetName + ".pdf";

                Worksheet workSheet = excelWorkbook.Sheets[sheetName];
                workSheet.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF
                    , fileName
                    , Type.Missing
                    , Type.Missing
                    , Type.Missing
                    , Type.Missing
                    , Type.Missing
                    , Type.Missing
                    , Type.Missing);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        ~ExcelFile()
        {
            this.Close();
        }
    }
}
